#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time     : 2025/4/24 19:35
# @Author   : MingTai
# @File     : video_to_grayscale.py
import cv2
import numpy as np
from concurrent.futures import ProcessPoolExecutor
from moviepy.editor import VideoFileClip, VideoClip
from app.utils.time_util.time_handle import get_second_time_str


def process_frame(frame):
    """将单帧转换为灰度图"""
    return cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)


def convert_video_to_grayscale(input_video_path, output_video_path):
    # 读取视频信息
    cap = cv2.VideoCapture(input_video_path)
    fps = cap.get(cv2.CAP_PROP_FPS)
    width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
    height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
    frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))

    # 读取音频
    video_clip = VideoFileClip(input_video_path)
    audio = video_clip.audio

    def frame_generator():
        """生成处理后的帧"""
        with ProcessPoolExecutor() as executor:
            futures = []
            while True:
                ret, frame = cap.read()
                if not ret:
                    break
                future = executor.submit(process_frame, frame)
                futures.append(future)

            for future in futures:
                gray_frame = future.result()
                # 由于 cv2.VideoWriter 要求彩色模式下是 3 通道，这里将单通道灰度图转为 3 通道
                gray_frame_3channel = cv2.cvtColor(gray_frame, cv2.COLOR_GRAY2BGR)
                yield gray_frame_3channel

    frame_gen = frame_generator()

    # 定义视频帧生成函数用于 moviepy
    def make_frame(t):
        frame_index = int(t * fps)
        if frame_index < frame_count:
            try:
                return next(frame_gen)
            except StopIteration:
                return np.zeros((height, width, 3), dtype=np.uint8)
        return np.zeros((height, width, 3), dtype=np.uint8)

    # 创建新的视频剪辑
    new_video_clip = VideoClip(make_frame, duration=video_clip.duration)
    new_video_clip = new_video_clip.set_audio(audio)

    # 写入新视频
    new_video_clip.write_videofile(output_video_path, fps=fps)

    # 释放资源
    cap.release()
    video_clip.close()


if __name__ == "__main__":
    input_video = 'video_color_20250424233438.mp4'  # 替换为实际的输入视频文件路径
    output_video = f'grayscale_video_{get_second_time_str()}.mp4'  # 替换为实际的输出视频文件路径
    convert_video_to_grayscale(input_video, output_video)
